import express, { Request, Response, NextFunction } from 'express';
import multer, { FileFilterCallback, MulterError } from 'multer';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';
import fs from 'fs';
import { UploadedFile, UploadResponse } from '../../types/upload';
import Jimp from 'jimp';

interface MulterRequest extends Request {
  file?: Express.Multer.File;
  files?: Express.Multer.File[] | { [fieldname: string]: Express.Multer.File[] };
}

const router = express.Router();

// 文件存储配置
const storage = multer.memoryStorage();

// 文件类型过滤器
const fileFilter = (_req: Request, file: Express.Multer.File, cb: FileFilterCallback) => {
  const allowedTypes = [
    'image/jpeg', 
    'image/png', 
    'application/pdf',
    'application/msword',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'application/vnd.ms-excel',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  ];
  
  if (allowedTypes.includes(file.mimetype)) {
    cb(null, true);
  } else {
    cb(new Error('不支持的文件类型'));
  }
};

// 添加压缩选项接口
interface UploadOptions {
  compress?: boolean;
}

// 修改文件保存函数，使用 Jimp 压缩
async function saveFile(file: Express.Multer.File, options: UploadOptions = {}): Promise<UploadedFile> {
  const appConfig = require('../../config/app').default;
  const today = new Date().toISOString().split('T')[0];
  let uploadDir = `${appConfig.uploadPath}/${today}`;
  
  console.log(`开始处理文件: ${file.originalname}, 大小: ${file.size} bytes, 类型: ${file.mimetype}`);
  
  if (uploadDir.startsWith('../')) {
    uploadDir = uploadDir.replace('../', '');
  }

  if (!fs.existsSync(uploadDir)) {
    fs.mkdirSync(uploadDir, { recursive: true });
    console.log(`创建上传目录: ${uploadDir}`);
  }

  let buffer = file.buffer;
  let mimetype = file.mimetype;

  // 检查是否需要压缩
  if (options.compress && file.size > 2 * 1024 * 1024 && file.mimetype.startsWith('image/')) {
    console.log(`文件大小超过2MB，开始压缩: ${file.originalname}`);
    try {
      const image = await Jimp.read(buffer);
      image.scaleToFit(1920, 1080);
      buffer = await image.quality(80).getBufferAsync(Jimp.MIME_JPEG);
      mimetype = 'image/jpeg';
      console.log(`压缩完成，压缩后大小: ${buffer.length} bytes，压缩率: ${((1 - buffer.length / file.size) * 100).toFixed(2)}%`);
    } catch (error) {
      console.error(`图片压缩失败: ${error}`);
      // 如果压缩失败，使用原始文件
      buffer = file.buffer;
    }
  }

  const filename = `${uuidv4()}${path.extname(file.originalname)}`;
  const filepath = path.join(uploadDir, filename);

  await fs.promises.writeFile(filepath, buffer);
  console.log(`文件保存成功: ${filepath}`);

  return {
    filename,
    originalname: file.originalname,
    path: `/uploads/${today}/${filename}`,
    size: buffer.length,
    mimetype
  };
}

// 修改单文件上传路由
router.post('/single', (req: MulterRequest, res: Response) => {
  console.log('开始处理单文件上传请求');
  const upload = multer({ storage, fileFilter, limits: { fileSize: 10 * 1024 * 1024 } }).single('file');

  upload(req, res, async (err) => {
    if (err) {
      console.error(`文件上传失败: ${err.message}`);
      return res.status(400).json({
        success: false,
        message: err.message
      } as UploadResponse);
    }

    try {
      if (!req.file) {
        console.warn('未上传文件');
        return res.status(400).json({
          success: false,
          message: '没有文件被上传'
        } as UploadResponse);
      }

      const fileInfo = await saveFile(req.file, { compress: true });
      console.log(`文件上传成功: ${fileInfo.path}`);

      res.json({
        success: true,
        message: '文件上传成功',
        data: fileInfo
      } as UploadResponse);
    } catch (error) {
      console.error('文件处理失败:', error);
      res.status(500).json({
        success: false,
        message: '文件上传失败',
        error: error instanceof Error ? error.message : '未知错误'
      } as UploadResponse);
    }
  });
});

// 修改多文件上传路由
router.post('/multiple', (req: MulterRequest, res: Response) => {
  console.log('开始处理多文件上传请求');
  const multipleUpload = multer({ 
    storage, 
    fileFilter, 
    limits: { fileSize: 10 * 1024 * 1024 } 
  }).array('files', 5);

  multipleUpload(req, res, async (err) => {
    if (err) {
      console.error(`文件上传失败: ${err.message}`);
      return res.status(400).json({
        success: false,
        message: err.message
      } as UploadResponse);
    }

    try {
      if (!req.files || !Array.isArray(req.files) || req.files.length === 0) {
        console.warn('未上传文件');
        return res.status(400).json({
          success: false,
          message: '没有文件被上传'
        } as UploadResponse);
      }

      console.log(`开始处理 ${req.files.length} 个文件`);
      const compress = req.query.compress !== 'false';
      console.log(`压缩选项: ${compress ? '开启' : '关闭'}`);

      const filesInfo = await Promise.all(
        req.files.map(file => saveFile(file, { compress }))
      );

      console.log(`所有文件处理完成，共 ${filesInfo.length} 个文件`);

      res.json({
        success: true,
        message: '文件上传成功',
        data: filesInfo
      } as UploadResponse);
    } catch (error) {
      console.error('文件处理失败:', error);
      res.status(500).json({
        success: false,
        message: '文件上传失败',
        error: error instanceof Error ? error.message : '未知错误'
      } as UploadResponse);
    }
  });
});

// 错误处理中间件
router.use((error: Error | MulterError, _req: Request, res: Response, _next: NextFunction) => {
  if (error instanceof MulterError) {
    if (error.code === 'LIMIT_FILE_SIZE') {
      return res.status(400).json({
        success: false,
        message: '文件大小超出限制'
      } as UploadResponse);
  }
}

res.status(500).json({
  success: false,
  message: error.message
} as UploadResponse);
});

export default router; 